﻿using System;
using System.Collections.Generic;
using System.Text;
using Jelly2013.Entity;

namespace Jelly2013
{
    public static class SubmitOrder
    {
        static string _referer = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=init";
        public static bool DoSubmitOrder(OrderInfo o, string verificationCode,ref string msg)
        {
            CheckOrderInfo(verificationCode);
            msg = "尊敬的旅客，本次列车您选择的席别尚有余票";
            msg = getQueueCount(o, msg);
            string url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=confirmSingleForQueueOrder";
            List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
            postData.Add(new KeyValuePair<string, string>("org.apache.struts.taglib.html.TOKEN", o.Token));
            postData.Add(new KeyValuePair<string, string>("textfield", "中文或拼音首字母"));
            postData.Add(new KeyValuePair<string, string>("leftTicketStr", o.Left_ticket));
            postData.Add(new KeyValuePair<string, string>("orderRequest.train_date", o.TicketInfo.TrainDate));
            postData.Add(new KeyValuePair<string, string>("orderRequest.train_no", o.TicketInfo.TrainNo));
            postData.Add(new KeyValuePair<string, string>("orderRequest.station_train_code", o.TicketInfo.StationTrainCode));
            postData.Add(new KeyValuePair<string, string>("orderRequest.from_station_telecode", o.TicketInfo.DepartureStationTelCode));
            postData.Add(new KeyValuePair<string, string>("orderRequest.to_station_telecode", o.TicketInfo.DestinationStationTelCode));
            postData.Add(new KeyValuePair<string, string>("orderRequest.seat_type_code", string.Empty));
            postData.Add(new KeyValuePair<string, string>("orderRequest.seat_detail_type_code", string.Empty));
            postData.Add(new KeyValuePair<string, string>("orderRequest.ticket_type_order_num", string.Empty));
            postData.Add(new KeyValuePair<string, string>("orderRequest.bed_level_order_num", "000000000000000000000000000000"));
            postData.Add(new KeyValuePair<string, string>("orderRequest.start_time", o.TicketInfo.DrivingTime));
            postData.Add(new KeyValuePair<string, string>("orderRequest.end_time", o.TicketInfo.ArrivalTime));
            postData.Add(new KeyValuePair<string, string>("orderRequest.from_station_name", o.TicketInfo.DepartureStation));
            postData.Add(new KeyValuePair<string, string>("orderRequest.to_station_name", o.TicketInfo.DestinationStation));
            postData.Add(new KeyValuePair<string, string>("orderRequest.cancel_flag", "1"));
            postData.Add(new KeyValuePair<string, string>("orderRequest.id_mode", "Y"));
            for (int i = 0; i < 5; i++)
            {
                    Passenger passenger = null;
                    if (i < o.Passengers.Count)
                    {
                        passenger = o.Passengers[i];
                        postData.Add(new KeyValuePair<string, string>("passengerTickets", passenger.PassengerTickets));
                        postData.Add(new KeyValuePair<string, string>("oldPassengers", passenger.OldPassengers));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_seat", passenger.SeatType));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_seat_detail", passenger.Seat_detail));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_ticket", passenger.PassengerTicket));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_name", passenger.Name));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_cardtype", passenger.IDCardType));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_cardno", passenger.CardNo));
                        postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_mobileno", passenger.MobileNo));
                    }
                    else
                    {
                        //postData.Add(new KeyValuePair<string, string>("passengerTickets", string.Empty));
                        postData.Add(new KeyValuePair<string, string>("oldPassengers", string.Empty));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_seat", "1"));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_seat_detail", "0"));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_ticket", "1"));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_name", string.Empty));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_cardtype", "1"));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_cardno", string.Empty));
                        //postData.Add(new KeyValuePair<string, string>("passenger_" + (i + 1) + "_mobileno", string.Empty));
                        //保存到常用联系人
                        postData.Add(new KeyValuePair<string, string>("checkbox9", "Y"));
                    }
                    
            }
            postData.Add(new KeyValuePair<string, string>("randCode", string.Empty));
            postData.Add(new KeyValuePair<string, string>("orderRequest.reserve_flag", "A"));
            string htmlStr = CommUitl.postString(url, postData, null, null, Encoding.UTF8, CommData.cookieCollection, _referer);
            Debug.Log(htmlStr);
            Struct_confirmSingleForQueueOrder s = Get_Result_confirmSingleForQueueOrder(htmlStr);
            if (s.errMsg!="Y")
            {
                throw new Exception("出票失败："+s.errMsg);
            }
            msg += Environment.NewLine + "订票成功！";
            msg += Environment.NewLine + "点击“确认”后会自动弹出浏览器并登入12306网站，请火速前往查看“未完成订单”进行支付！";
            //TODO:Debug
            return true;
        }

        private static string getQueueCount(OrderInfo o, string desc)
        {
            string url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=getQueueCount" +
                "&train_date=" + o.TicketInfo.TrainDate +
                "&train_no=" + o.TicketInfo.TrainNo +
                "&station=" + o.TicketInfo.StationTrainCode +
                "&seat=" + o.Passengers[0].SeatType +
                "&from=" + o.TicketInfo.DepartureStationTelCode +
                "&to=" + o.TicketInfo.DestinationStationTelCode +
                "&ticket=" + o.Left_ticket;
            string htmlStr;
            try
            {
                htmlStr = CommUitl.getString(url, CommData.cookieContainer, _referer);
                Debug.Log(htmlStr);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            Struct_getQueueCount result = Get_Result_GetQueueCount(htmlStr);
            desc += getTicketCountDesc(result.ticket, o.Passengers[0].SeatType);
            if (result.op_2)
            {
                desc += "目前排队人数已经超过余票张数，请您选择其他席别或车次，特此提醒。";
                throw new Exception(desc);
            }
            else if (Convert.ToInt32(result.countT) > 0)
            {
                desc += "目前排队人数【" + result.countT + "】人，";
            }
            return desc;
        }

        private static string getTicketCountDesc(string mark,string seat)
        {
            string desc = "";
            int seat_1 = -1;
            int seat_2 = -1;
            int i = 0;
            while (i < mark.Length)
            {
                string s = mark.Substring(i, 10);
                string c_seat = s.Substring(0, 1);
                if (c_seat == seat)
                {
                    string count = s.Substring(6, 4);
                    int temp = Convert.ToInt32(count);
                    if (temp < 3000)
                    {
                        seat_1 = temp;
                    }
                    else
                    {
                        seat_2 = (temp - 3000);
                    }
                }
                i = i + 10;
            }

            if (seat_1 > -1)
            {
                desc += "【" + seat_1 + "】张";
            }
            if (seat_2 > -1)
            {
                desc += ",无座【" + seat_2 + "】张";
            }
            desc += "，";
            return desc;
        }
        /// <summary>
        /// {"countT":0,"count":0,"ticket":"10207038494062700000102070111920345000433038500000","op_1":false,"op_2":true}
        /// </summary>
        /// <param name="htmlStr"></param>
        /// <returns></returns>
        private static Struct_getQueueCount Get_Result_GetQueueCount(string htmlStr)
        {
            Struct_getQueueCount s = new Struct_getQueueCount();
            htmlStr = htmlStr.Replace("\"", string.Empty);
            htmlStr = htmlStr.Replace("}", string.Empty);
            string[] items = htmlStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            s.countT = items[0].Split(':')[1];
            s.count = items[1].Split(':')[1];
            s.ticket = items[2].Split(':')[1];
            s.op_1 = Convert.ToBoolean(items[3].Split(':')[1]);
            s.op_2 = Convert.ToBoolean(items[4].Split(':')[1]);
            return s;
        }
        private static void CheckOrderInfo(string verificationCode)
        {
            string url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=checkOrderInfo&rand=" + verificationCode;
            List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
            postData.Add(new KeyValuePair<string, string>("tFlag", "dc"));
            string htmlStr;
            try
            {
                htmlStr = CommUitl.postString(url, postData, null, null, Encoding.UTF8, CommData.cookieCollection, _referer);
                Debug.Log(htmlStr);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("登陆"))
                {
                    throw new Exception("您离开页面的时间过长，请重新登录系统。");
                }
                throw new Exception("服务器繁忙，请稍候再试！");
            }
            Struct_checkOrderInfo result = Get_Result_CheckOrderInfo(htmlStr);
            if (result.errMsg != "Y")
            {
                throw new Exception(result.errMsg);
            }
            else if ("N" == result.checkHuimd)
            {
                throw new Exception("对不起，由于您取消次数过多，今日将不能继续受理您的订票请求！");
            }
            else if ("N" == result.check608)
            {
                throw new Exception(result.msg);
            }
        }
        /// <summary>
        /// {"checkHuimd":"Y","check608":"Y","msg":"","errMsg":"验证码 必须输入."}
        /// </summary>
        /// <param name="htmlStr"></param>
        /// <returns></returns>
        private static Struct_checkOrderInfo Get_Result_CheckOrderInfo(string htmlStr)
        {
            Struct_checkOrderInfo s = new Struct_checkOrderInfo();
            htmlStr = htmlStr.Replace("\"", string.Empty);
            htmlStr = htmlStr.Replace("}",string.Empty);
            string[] items = htmlStr.Split(new string[]{","},StringSplitOptions.RemoveEmptyEntries);
            s.checkHuimd = items[0].Split(':')[1];
            s.check608 = items[1].Split(':')[1];
            s.msg = items[2].Split(':')[1];
            s.errMsg = items[3].Split(':')[1];
            return s;
        }
        private static Struct_confirmSingleForQueueOrder Get_Result_confirmSingleForQueueOrder(string htmlStr)
        {
            Struct_confirmSingleForQueueOrder s = new Struct_confirmSingleForQueueOrder();
            htmlStr = htmlStr.Replace("\"", string.Empty);
            htmlStr = htmlStr.Replace("}", string.Empty);
            string[] items = htmlStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            s.errMsg = items[0].Split(':')[1];
            return s;
        }
        private struct Struct_confirmSingleForQueueOrder
        {
            public string errMsg;
        }
        private struct Struct_getQueueCount
        {
            public string count;
            public string countT;
            public string ticket;
            public bool op_1;
            public bool op_2;
        }
        private struct Struct_checkOrderInfo
        {
            public string checkHuimd;
            public string check608;
            public string msg;
            public string errMsg;
        }
    }
}
